﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using ECommon.IO;
using ESTAR.Infrastructure;
using MySql.Data.MySqlClient;

namespace ESTAR.Denormalizers.Dapper
{
    public abstract class AbstractDenormalizer
    {
        protected async Task TryInsertRecordAsync(Func<IDbConnection, Task<long>> action, string DbName)
        {
            try
            {
                using (var connection = GetConnection(DbName))
                {
                    await action(connection);
                }
            }
            catch (MySqlException ex)
            {
                if (ex.Number == 2627)  //主键冲突，忽略即可；出现这种情况，是因为同一个消息的重复处理
                {
                    return;
                }
                throw new IOException("Insert record failed.", ex);
            }
        }
        protected async Task TryUpdateRecordAsync(Func<IDbConnection, Task<int>> action, string DbName)
        {
            try
            {
                using (var connection = GetConnection(DbName))
                {
                    await action(connection);
                }
            }
            catch (MySqlException ex)
            {
                throw new IOException("Update record failed.", ex);
            }
        }

        protected async Task TryRunTransactionAsync(Func<IDbConnection, IDbTransaction, Task<int>> action, string DbName)
        {
            using (var connection = GetConnection(DbName))
            {
                connection.Open();
                var transaction = connection.BeginTransaction();
                try
                {
                    await action(connection, transaction);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw new IOException("Transaction rollback.", ex);
                }
            }
        }
        protected async Task TryRunTransactionAsync(Func<IDbConnection, IDbTransaction, Task<long>> action, string DbName)
        {
            using (var connection = GetConnection(DbName))
            {
                connection.Open();
                var transaction = connection.BeginTransaction();
                try
                {
                    await action(connection, transaction);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw new IOException("Transaction rollback.", ex);
                }
            }
        }

        protected IDbConnection GetConnection(string DbName)
        {
            return new MySqlConnection(ConfigSettings.EStarConnectionString[DbName]);
        }
    }
}
